<?php
/**
 * Created by PhpStorm.
 * User: aDaddy
 * Date: 2016/7/25
 * Time: 9:55
 */

namespace App\Model\LazyCommon;
use App\Base\BaseConfig;
use App\Base\BaseModel;
use BaseExt\MyCurl;

class WechatModel extends BaseModel{

    public $AppId; //服务号APPId
    public $AppSecret; //服务号APPId

    public $Code;
    public $AccessToken;
    public $JsApiTicket;
    public $Openid; //商户appid下，用户的openid
    public $url;//请求连接地址
    public $curl_timeout;//请求超时时间
    public $response;//接口返回信息

    public function __construct($doctrine)
    {
        parent::__construct($doctrine);
        $this->AppId = BaseConfig::__WECHAT_PLAT_APPID__;
        $this->AppSecret = BaseConfig::__WECHAT_PLAT_APPSEC__;
    }


    public function getWeChatCode($callBackUrl,$popurse = 0,$STATE="")
    {
        $scopeChoice = [
            "snsapi_base",//用来获取进入页面的用户的openid的，并且是静默授权并自动跳转到回调页的。
            "snsapi_userinfo"//用来获取用户的基本信息的。但这种授权需要用户手动同意，并且由于用户同意过，所以无须关注，就可在授权后获取该用户的基本信息。
        ];
        $APPID = $this->AppId;
        $REDIRECT_URI = $callBackUrl;
        $REDIRECT_URI = urlencode($REDIRECT_URI);
        $SCOPE = $scopeChoice[$popurse];
        $url = "https://open.weixin.qq.com/connect/oauth2/authorize?";
        $url .= "appid=$APPID";
        $url .= "&redirect_uri=$REDIRECT_URI";
        $url .= "&response_type=code&scope=$SCOPE&state=$STATE#wechat_redirect";
        header("location:$url");
        return $url;
    }

    public function getOpenidAndAccessToken($code)
    {
        $this->Code = $code;
        $APPID = $this->AppId;
        $SECRET = $this->AppSecret;
        $CODE = $this->Code;
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?";
        $url .= "appid=$APPID";
        $url .= "&secret=$SECRET";
        $url .= "&code=$CODE&grant_type=authorization_code";
        $return = $this->myCurl($url);//这些接口返回的都是字符串形式
        $return = json_decode($return,true);
        if (!isset($return["openid"])) {
            //code有可能被使用了，需要重新定向到原始页面
            return false;
        }
        $this->AccessToken = $return["access_token"];
        $this->Openid = $return["openid"];
        return true;
    }

    public function getAccessToken(){
        $str = file_get_contents("./../FileData/access_token.txt");
        if ($str) {
            $data = json_decode($str,true);
            if ($data["time"] > time() + 6000  && isset($data["access_token"]) && $data["access_token"]) {
                return $data["access_token"];
            }
        }
        $APPID = $this->AppId;
        $SECRET = $this->AppSecret;
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$APPID&secret=$SECRET";
        $return = $this->myCurl($url);//这些接口返回的都是字符串形式
        $data = json_decode($return,true);
        $json["access_token"] = $data["access_token"];
        $this->AccessToken = $data["access_token"];
        $json["time"] = $data["expires_in"] + time();
        file_put_contents("./../FileData/access_token.txt",json_encode($json));
        return $json["access_token"];
    }

    public function getJsApiTicket()
    {
        $str = file_get_contents("./../FileData/ticket.txt");
        if ($str) {
            $data = json_decode($str,true);
            if ($data["time"] > time() + 60) {
                $this->JsApiTicket = $data["ticket"];
                return $data["ticket"];
            }
        }
        $ACCESS_TOKEN = $this->getAccessToken();
        $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$ACCESS_TOKEN&type=jsapi";
        $return = $this->myCurl($url);//这些接口返回的都是字符串形式
        $return = json_decode($return,true);
        $json["ticket"] = $return["ticket"];
        $json["time"] = $return["expires_in"] + time();
        file_put_contents("./../FileData/ticket.txt",json_encode($json));
        $this->JsApiTicket = $json["ticket"];
        return $json["ticket"];
    }


    public function createJsApiParam($url)
    {
        //微信分享签名
        $now = time();
        $param["appId"] = $this->AppId;
        $param["timestamp"] = $now;
        $param["noncestr"] = $this->createNoncestr();
        $param["url"] = $url;
        $param["signature"] = $this->getJsApiSign($param);
        return $param;
    }


    public function getAccessToken4UserInfo($code)
    {
        $this->Code = $code;
        $APPID = $this->AppId;
        $SECRET = $this->AppSecret;
        $CODE = $this->Code;
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?";
        $url .= "appid=$APPID";
        $url .= "&secret=$SECRET";
        $url .= "&code=$CODE&grant_type=authorization_code";
        $return = $this->myCurl($url);//这些接口返回的都是字符串形式
        $return = json_decode($return,true);
        $this->AccessToken = $return["access_token"];
        $this->Openid = $return["openid"];
    }

    /**
     * @return WeChatUserInfo
     */
    public function getWeChatUserInfo()
    {
        $ACCESS_TOKEN = $this->AccessToken;
        $OPENID = $this->Openid;
        $url = "https://api.weixin.qq.com/sns/userinfo?".
            "access_token=$ACCESS_TOKEN&openid=$OPENID&lang=zh_CN";
        $return = $this->myCurl($url);//这些接口返回的都是字符串形式
        return $this->createUserInfo($return);
    }


    /**
     * 	作用：去除空格
     */
    protected function trimString($value)
    {
        $ret = null;
        if (null != $value)
        {
            $ret = $value;
            if (strlen($ret) == 0)
            {
                $ret = null;
            }
        }
        return $ret;
    }

    /**
     * 	作用：post请求xml
     */
    protected function postXml()
    {
        $xml = $this->createXml();//每个扩展此controller的需要自己创建createXml
        $this->response = $this->postXmlCurl($this->url,$xml);
        return $this->response;
    }



    /**
     * 	作用：产生随机字符串，不长于32位
     */
    public function createNoncestr( $length = 32 )
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str ="";
        for ( $i = 0; $i < $length; $i++ )  {
            $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
        }
        return $str;
    }

    /**
     * 	作用：生成签名
     */
    public function getSign($Obj)
    {
        foreach ($Obj as $k => $v)
        {
            $Parameters[$k] = $v;
        }
        //签名步骤一：按字典序排序参数
        ksort($Parameters);
        $String = $this->formatBizQueryParaMap($Parameters, false);
        //echo '【string1】'.$String.'</br>';
        //签名步骤二：在string后加入KEY
        $String = $String."&key=".$this->PayAccountKey;
        //echo "【string2】".$String."</br>";
        //签名步骤三：MD5加密
        $String = md5($String);
        //echo "【string3】 ".$String."</br>";
        //签名步骤四：所有字符转为大写
        $result_ = strtoupper($String);
        // echo "【result】 ".$result_."</br>";
        return $result_;
    }
    /**
     * 	作用：生成签名
     */
    public function getJsApiSign($param)
    {
        $jsapi_ticket = $this->JsApiTicket;
        $timestamp = $param["timestamp"];
        $noncestr = $param["noncestr"];
        $url = $param["url"];
//        $this->log_out("jsapi_ticket=$jsapi_ticket&noncestr=$noncestr&timestamp=$timestamp&url=$url");
//        $this->log_out(sha1("jsapi_ticket=$jsapi_ticket&noncestr=$noncestr&timestamp=$timestamp&url=$url"));
        return sha1("jsapi_ticket=$jsapi_ticket&noncestr=$noncestr&timestamp=$timestamp&url=$url");
    }

    /**
     * 	作用：array转xml
     */
    protected function arrayToXml($arr)
    {

        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        {
            if (is_numeric($val))
            {
                $xml.="<".$key.">".$val."</".$key.">";

            }
            else
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
        }
        $xml.="</xml>";
        return $xml;
    }

    /**
     * 	作用：以post方式提交xml到对应的接口url
     */
    public  function postXmlCurl($url,$xml){
        $ch=curl_init();
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_HEADER,1);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,1);//证书检查
        curl_setopt($ch,CURLOPT_SSLCERTTYPE,'pem');
        curl_setopt($ch,CURLOPT_SSLCERT,'./../FileData/cert/apiclient_cert.pem');
        curl_setopt($ch,CURLOPT_SSLCERTTYPE,'pem');
        curl_setopt($ch,CURLOPT_SSLKEY,'./../FileData/cert/apiclient_key.pem');
//        curl_setopt($ch,CURLOPT_SSLCERTTYPE,'pem');
//        curl_setopt($ch,CURLOPT_CAINFO,'/Data/code/songshu/public/chart/cert/rootca.pem');
        curl_setopt($ch,CURLOPT_POST,1);
        curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);
        $data=curl_exec($ch);

        if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == '200') {
            $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
            $header = substr($data, 0, $headerSize);
            $body = substr($data, $headerSize);
            $receiveData = json_decode(json_encode(simplexml_load_string($body, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
            $result_code = $receiveData['result_code'];
            // $receiveData['data'] = $data;
            return $receiveData;
        }else{
            $error=curl_errno($ch);
            curl_close($ch);
            return 2;
        }
    }

    /**
     * 	作用：将xml转为array
     */
    public function xmlToArray($xml)
    {
        //将XML转为array
        $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $array_data;
    }

    /**
     * 	作用：格式化参数，签名过程需要使用
     */
    function formatBizQueryParaMap($paraMap, $urlencode)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v)
        {
            if($urlencode)
            {
                $v = urlencode($v);
            }
            //$buff .= strtolower($k) . "=" . $v . "&";
            $buff .= $k . "=" . $v . "&";
        }
        $reqPar = "";
        if (strlen($buff) > 0)
        {
            $reqPar = substr($buff, 0, strlen($buff)-1);
        }
        return $reqPar;
    }



    public function myCurl($url){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
//        curl_setopt($curl, CURLOPT_HEADER, 1);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);//这个是重点。
        $data = curl_exec($curl);
        curl_close($curl);
        return $data;    //返回json对象
    }




    public function sendTemplateMessage($toUser , $title,$keyword1,$keyword2,$remark,$urlDeal="")
    {
        if (!$ACCESS_TOKEN = $this->getAccessToken()) {
//            var_dump($this->AccessToken);
            die;
        }
        $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$ACCESS_TOKEN";


        $MyCurl = new MyCurl();
        if (!$toUser) {
            $OPENID = "oQ_Fh1uqeyXRmTweTA2zoTh_sxqg";
        }else{
            $OPENID = $toUser;
        }

        $data = '{
           "touser":"'.$OPENID.'",
           "template_id":"iGYrkX6d09klYKnQSzGJfR9qBztQxXuXOfCh-805cD4",
           "url":"'.$urlDeal.'",
	       "topcolor": "#FF0000",
           "data":{
                   "first": {
                       "value":"'.$title.'",
                       "color":"#173177"
                   },
                   "keyword1":{
                       "value":"'.$keyword1.'",
                       "color":"#173177"
                   },
                   "keyword2": {
                       "value":"'.$keyword2.'",
                       "color":"#173177"
                   },
                   "remark":{
                       "value":"'.$remark.'",
                       "color":"#173177"
                   }
           }
       }';
        $MyCurl->post($url,$data);

//        $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$ACCESS_TOKEN";
//
//
//        $MyCurl = new MyCurl();
//        if (!$toUser) {
//            $OPENID = "oySZl1PQeQouIJvsrsgxp4PecCu0";
//        }else{
//            $OPENID = $toUser;
//        }
//
//
////        "url":"'.$urlDeal."&openId=$OPENID".'",
//        var_dump("-------------");
//        var_dump($OPENID);
//        var_dump($title);
//        var_dump($keyword1);
//        var_dump($keyword2);
//        var_dump($remark);
//        var_dump("-------------");
//        $data = '{
//           "touser":'.$OPENID.',
//           "template_id":"iGYrkX6d09klYKnQSzGJfR9qBztQxXuXOfCh-805cD4",
//           "data":{
//                   "first": {
//                       "value":"'.$title.'",
//                       "color":"#173177"
//                   },
//                   "keyword1":{
//                       "value":"'.$keyword1.'",
//                       "color":"#173177"
//                   },
//                   "keyword2": {
//                       "value":"'.$keyword2.'",
//                       "color":"#173177"
//                   },
//                   "remark":{
//                       "value":"'.$remark.'",
//                       "color":"#173177"
//                   }
//           }
//       }';
//        $data = json_encode(json_decode($data));
////        $data = (json_decode($data));
//        var_dump($data);
//        $MyCurl->post($url,$data);
    }

    //设置网络请求配置//todo 暂时未使用
    public function _request($curl,$https=true,$method='GET',$data=null){
        // 创建一个新cURL资源
        $ch = curl_init();

        // 设置URL和相应的选项
        curl_setopt($ch, CURLOPT_URL, $curl);    //要访问的网站
        curl_setopt($ch, CURLOPT_HEADER, false);    //启用时会将头文件的信息作为数据流输出。
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);  //将curl_exec()获取的信息以字符串返回，而不是直接输出。

        if($https){
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);  //FALSE 禁止 cURL 验证对等证书（peer's certificate）。
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true);  //验证主机
        }
        if($method == 'POST'){
            curl_setopt($ch, CURLOPT_POST, true);  //发送 POST 请求
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);  //全部数据使用HTTP协议中的 "POST" 操作来发送。
        }


        // 抓取URL并把它传递给浏览器
        $content = curl_exec($ch);
        if ($content  === false) {
            return "网络请求出错: " . curl_error($ch);
            exit();
        }
        //关闭cURL资源，并且释放系统资源
        curl_close($ch);
        return $content;
    }

    /**
     * @param $json
     * @return WeChatUserInfo
     */
    public function createUserInfo($json)
    {
        $UserInfo = new WeChatUserInfo();
        $data = json_decode($json,true);
        foreach ($data as $key => $val) {
            $UserInfo->$key = $val;
        }
        return $UserInfo;
    }


}
//没有别的意思，就是要他的代码提示
class WeChatUserInfo
{
    public $openid;
    public $nickname;
    public $sex;
    public $province;
    public $city;
    public $country;
    public $headimgurl;
    public $privilege;
    public $unionid;
}